/*
 *    Copyright (c) 2018-2025, boss All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the boss developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: boss
 */
package com.hopes.bizz.risk.setting.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hopes.bizz.common.core.util.StringUtils;
import com.hopes.bizz.risk.common.constant.RiskDicConstant;
import com.hopes.bizz.risk.common.constant.enums.RiskSysDictEnum;
import com.hopes.bizz.risk.setting.constant.RiskSettingConstant;
import com.hopes.bizz.risk.setting.dto.RiskConfigLsExcelDTO;
import com.hopes.bizz.risk.setting.entity.RiskConfigLEntity;
import com.hopes.bizz.risk.setting.entity.RiskConfigLsEntity;
import com.hopes.bizz.risk.setting.entity.RiskConfigScEntity;
import com.hopes.bizz.risk.setting.mapper.RiskConfigLsMapper;
import com.hopes.bizz.risk.setting.service.RiskConfigLService;
import com.hopes.bizz.risk.setting.service.RiskConfigLsService;
import com.hopes.bizz.risk.setting.service.RiskConfigScService;
import com.hopes.bizz.risk.setting.vo.RiskConfigLVO;
import com.hopes.bizz.risk.setting.vo.RiskConfigLsExcelVO;
import com.hopes.bizz.risk.setting.vo.RiskLecIdentifyVO;
import com.hopes.bizz.risk.setting.vo.RiskLsIdentifyVO;
import com.hopes.boss.admin.api.resolver.DictResolver;
import com.hopes.boss.common.entity.ValidateImportBO;
import com.hopes.boss.common.excel.vo.ErrorMessage;
import com.hopes.boss.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * LS评级结果设置
 *
 * @author pig
 * @date 2023-07-17 19:43:01
 */
@Service
@RequiredArgsConstructor
public class RiskConfigLsServiceImpl extends ServiceImpl<RiskConfigLsMapper, RiskConfigLsEntity> implements RiskConfigLsService {

    private final RiskConfigLService riskConfigLService;
    private final RiskConfigScService riskConfigScService;

    @Override
    public Map<String, Object> initMap(RiskConfigLsEntity riskConfigLs) {
        final Map<String, Object> result = new HashMap<>();

        final LambdaQueryWrapper<RiskConfigLEntity> configLWrapper = Wrappers.<RiskConfigLEntity>lambdaQuery()
                .eq(RiskConfigLEntity::getDelFlag, Boolean.FALSE)
                .eq(RiskConfigLEntity::getModuleCode, RiskSettingConstant.MODULE_LS);
        final long countL = riskConfigLService.count(configLWrapper);

        final LambdaQueryWrapper<RiskConfigScEntity> configScWrapper = Wrappers.<RiskConfigScEntity>lambdaQuery()
                .eq(RiskConfigScEntity::getDelFlag, Boolean.FALSE)
                .eq(RiskConfigScEntity::getModuleCode, RiskSettingConstant.MODULE_LS);
        final long countS = riskConfigScService.count(configScWrapper);

        final LambdaQueryWrapper<RiskConfigLsEntity> queryWrapper = Wrappers.<RiskConfigLsEntity>lambdaQuery()
                .eq(RiskConfigLsEntity::getDelFlag, Boolean.FALSE);
        final List<RiskConfigLsEntity> entityList = this.list(queryWrapper);
        result.put("countL", countL);
        result.put("countS", countS);
        result.put("dataList", entityList);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RiskLsIdentifyVO initIdentifyData() {
        final RiskLsIdentifyVO riskLsIdentifyVO = new RiskLsIdentifyVO();

        riskLsIdentifyVO.setRiskLevelList(DictResolver.getItemsByType(RiskSysDictEnum.risk_level));

        final LambdaQueryWrapper<RiskConfigLEntity> wrapper = Wrappers.<RiskConfigLEntity>lambdaQuery()
                .eq(RiskConfigLEntity::getModuleCode, RiskDicConstant.MODULE_LS);
        final List<RiskConfigLEntity> riskConfigLEntityList = riskConfigLService.list(wrapper);
        riskLsIdentifyVO.setRiskLsLList(RiskLecIdentifyVO.entity2VO(riskConfigLEntityList));

        final List<RiskConfigScEntity> riskConfigScEntityList = riskConfigScService.list();
        riskLsIdentifyVO.setRiskLsSList(RiskLsIdentifyVO.entity2VO(riskConfigScEntityList));

        final int countL = riskLsIdentifyVO.getRiskLsLList().size();
        final int countS = riskLsIdentifyVO.getRiskLsSList().size();
        if (countL > 0 && countS > 0) {
            /* LS辨识数据 */
            List<RiskConfigLsEntity> list = this.list();
            if (list.size() == 0) {
                list = buildRiskConfigLsList(countL, countS);
                saveBatch(list);
            }
            riskLsIdentifyVO.setRiskLsConfigList(list);
        }
        return riskLsIdentifyVO;
    }

    private List<RiskConfigLsEntity> buildRiskConfigLsList(int countL, int countS) {
        final List<RiskConfigLsEntity> riskConfigLsList = new ArrayList<>();
        for (int i = 1; i <= countL; i++) {
            for (int j = 1; j <= countS; j++) {
                final RiskConfigLsEntity riskConfigLsEntity = new RiskConfigLsEntity();
                riskConfigLsEntity.setRiskLevel(RiskDicConstant.MIN_RISK_LEVEL);
                riskConfigLsEntity.setRiskValue(i * j);
                riskConfigLsEntity.setCoordinate(i + StringUtils.COMMA + j);
                riskConfigLsList.add(riskConfigLsEntity);
            }
        }
        return riskConfigLsList;
    }

    @Override
    public Integer getLsRiskLevel(@Nullable String riskDesc) {
        if (StringUtil.isEmpty(riskDesc)) {
            return null;
        }
        final List<RiskConfigLsEntity> configLsEntityList = baseMapper.selectList(Wrappers.<RiskConfigLsEntity>lambdaQuery().orderByAsc(RiskConfigLsEntity::getRiskLevel));
        if (CollectionUtil.isEmpty(configLsEntityList)) {
            return null;
        }
        for (RiskConfigLsEntity riskConfigLs : configLsEntityList) {
            final StringBuilder sb = new StringBuilder();
            sb.append("L(").append(riskConfigLs.getCoordinate().replace(",", ")xS(")).append(")");
            if (riskDesc.contains(sb.toString())) {
                return riskConfigLs.getRiskLevel();
            }
        }
        return null;
    }


    @Override
    public ValidateImportBO<RiskConfigLsExcelDTO> validateImport(List<RiskConfigLsExcelDTO> excelDTOList) {
        ValidateImportBO<RiskConfigLsExcelDTO> bo = new ValidateImportBO<>();
        List<ErrorMessage> errorMessageList = new ArrayList<>();
        List<RiskConfigLsExcelDTO> saveList = new ArrayList<>(excelDTOList);
        int successNum = excelDTOList.size();
        int failedNum = 0;

        bo.setErrorMessages(errorMessageList);
        bo.setSaveList(saveList);
        bo.setSuccessNum(successNum);
        bo.setFailedNum(failedNum);
        return bo;
    }

    @Override
    public RiskConfigLsEntity importDtoToEntity(RiskConfigLsExcelDTO excelDto) {
        RiskConfigLsEntity entity= new RiskConfigLsEntity();
        BeanUtils.copyProperties(excelDto, entity);
        return entity;
    }

    @Override
    public RiskConfigLsExcelVO exportEntityToVo(RiskConfigLsEntity entity) {
        RiskConfigLsExcelVO excelVO = new RiskConfigLsExcelVO();
        BeanUtils.copyProperties(entity, excelVO);
        return excelVO;
    }

}
